﻿using System;
using WeDonekRpc.Client;
using WeDonekRpc.Client.Interface;
using WeDonekRpc.Client.Ioc;
using WeDonekRpc.Client.Track.Model;
using WeDonekRpc.Helper;
using WeDonekRpc.HttpApiGateway.Collect;
using WeDonekRpc.HttpApiGateway.Interface;
using WeDonekRpc.HttpService;
using WeDonekRpc.HttpService.Handler;
namespace WeDonekRpc.HttpApiGateway.Handler
{

    internal class HttpApiHandler : BasicHandler, IApiHandler
    {
        private readonly IApiRoute _Route = null;
        private static readonly IIocService _Ioc = RpcClient.Ioc;
        private IUpFileConfig _UpConfig;
        [ThreadStatic]
        public static IService ApiService = null;
        private IService _ApiService = null;
        public HttpApiHandler (IApiRoute route) : base(route.ApiUri, 99, route.IsRegex)
        {
            this._Route = route;
        }
        public override void ExecError (Exception error)
        {
            ErrorException ex = ErrorException.FormatError(error);
            this._ApiService.ReplyError(ex.ToString());
        }

        protected sealed override bool InitHandler ()
        {
            if (ApiPlugInService.Request_Init(this._Route, this))
            {
                using (IocScope scope = _Ioc.CreateScore())
                {
                    this._UpConfig = this._Route.CreateUpFileConfig(scope);
                    this._ApiService = new ApiService(this, this._Route);
                    HttpApiHandler.ApiService = this._ApiService;
                    this._Route.ReceiveRequest(this._ApiService);
                    return !this._ApiService.IsError;
                }
            }
            return false;
        }

        protected override bool CheckCache (string etag, string toUpdateTime)
        {
            return this._ApiService.CheckCache(etag, toUpdateTime);
        }
        public override void Execute ()
        {
            if (!GatwewayTrackCollect.CheckIsTrace(this._ApiService, out long spanId))
            {
                this._Route.ExecApi(this._ApiService);
                return;
            }
            using (TrackBody track = GatwewayTrackCollect.CreateTrack(this._ApiService, spanId))
            {
                this._Route.ExecApi(this._ApiService);
                GatwewayTrackCollect.EndTrack(track, this._ApiService);
            }
        }
        public override void VerificationFile (UpFileParam param, long fileSize)
        {
            this._UpConfig.CheckFileSize(this._ApiService, fileSize);
        }
        public override void InitFileUp ()
        {
            this._UpConfig.InitFileUp(this._ApiService);
        }
        public override void CheckUpFile (UpFileParam param)
        {
            this._UpConfig.CheckUpFormat(this._ApiService, param.FileName, this.Request.Files.Count + 1);
        }
        public override void End ()
        {
            this._ApiService?.End();
            base.End();
        }
        public override void Dispose ()
        {
            if (this._ApiService != null)
            {
                this._ApiService.Dispose();
                this._ApiService = null;
            }
            base.Dispose();
        }
    }
}
